
/*
 *  Index.cpp
 *
 *	Copyright (C) 2012
 *	Crane <szcshui@gmail.com>
 *	All Rights Reserved
 *
 *************************************************************************
 *
 *  Description:
 *      This file implements memory cache for used index file 
 *
 */

#include "Index.h"
#include <iostream>
#include <fstream>

Index::Index(const string& fileName, bool onlyAccount)
{
#ifdef _TRACE
	cout << "loading index file to cache :" << fileName << endl;
#endif
	ReadFromFile(fileName, onlyAccount);
}


Index::~Index(void)
{
	ClearMap(indexAccount);
	ClearMap(indexAccountSecurity);
}


bool Index::ReadFromFile(const string& fileName, bool onlyAccount)
{
	ifstream  inputFile;
	try
	{
		inputFile.open(fileName.c_str());

		if (inputFile.is_open())
		{
			string line;
			while (getline(inputFile, line))
			{
				ParseLine(line, onlyAccount);
			}

			inputFile.close();
		}
		else
		{
			cout << "open index file " << fileName << " failed!"  << endl;
		}
	}
	catch(exception &e )
	{
		cerr << e.what() << endl;
		return false;
	}
	return true;
}

void Index::ClearMap(map<string, vector<string> >& dict)
{
	for(map<string, vector<string> >::iterator itr = dict.begin();
		itr != dict.end(); itr++)
	{
		itr->second.clear();
	}

	dict.clear();
}

void Index::InsertToMap(map<string, vector<string> >& dict, string key, string value)
{
	if (dict.find(key) == dict.end())
	{
		vector<string> vec;
		vec.push_back(value);
		dict.insert(pair<string, vector<string> >(key, vec));
	}
	else
	{
		dict[key].push_back(value);
	}
}

bool Index::ParseLine(const string& line, bool onlyAccount)
{
	if (!line.empty())
	{
		int pos = line.find('|');
		if (pos != -1)
		{
			string accountSecurity = line.substr(0, pos);
			string offset = line.substr(pos+1, line.length() - pos-1);
			int posAccount = accountSecurity.find(':');
			string account = accountSecurity.substr(0, posAccount);
			
			if (onlyAccount)
			{
				InsertToMap(indexAccount, account, offset);
			}
			else
			{
				InsertToMap(indexAccountSecurity, accountSecurity, offset);
			}

			return true;
		}
	}

	return false;
}

vector<string> Index::GetOffsetList(const string &key,  bool onlyAccount)
{
	map<string, vector<string> > dict = onlyAccount? indexAccount: indexAccountSecurity;

	map<string, vector<string> >::iterator itr = dict.find(key);

	if (itr == dict.end())
	{
		return vector<string>();
	}
	else
	{
		return itr->second;
	}
	
}